package com.woniu.servicepay.mqConsumer;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
import com.woniu.internalcommon.request.OrderRequest;
import com.woniu.servicepay.config.PayMQConfig;
import com.woniu.servicepay.feignClient.OrderFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
@Slf4j
public class PaymentSuccessListener {
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 处理支付成功的订单
     * @param orderId
     */
    @RabbitListener(queues = PayMQConfig.PAY_QUEUE)
    public void handlePaymentSuccess(Long orderId, Channel channel, Message message) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        log.info("收到支付成功消息: {}", orderId);
        //以orderId为key，查看redis中是否存在该订单
        Integer retryCount = (Integer) redisTemplate.opsForValue().get("orders::"+orderId);
        if (retryCount == null) {
            //设置初始重试次数为0
            redisTemplate.opsForValue().set("orders::"+orderId, 0);
        }

        try {
            System.out.println("处理订单业务逻辑");
            // 处理订单业务逻辑
            boolean success = processOrder(orderId);
            if (success) {
                // 业务处理成功，手动确认消息
                channel.basicAck(deliveryTag, false);
                //从redis删除该订单
                redisTemplate.delete("orders::"+orderId);
                log.info("订单处理完成并确认, orderId: {}", orderId);
            }else{
                handleFailure(channel, message, deliveryTag, retryCount, orderId);
            }

        } catch (Exception e) {
            // 业务异常，记录日志后拒绝消息并重新入队
            log.error("业务处理异常，订单重新入队, orderId: " + orderId, e);
            channel.basicNack(deliveryTag, false, true);
        }
    }

    private void handleFailure(Channel channel, Message message, long deliveryTag, Integer retryCount, Long orderId) {
        if (retryCount < PayMQConfig.MAX_RETRY_COUNT) {
            // 增加重试次数
            redisTemplate.opsForValue().set("orders::"+orderId, retryCount + 1);
            //重入队列
            try {
                channel.basicPublish(
                        "",
                        message.getMessageProperties().getConsumerQueue(),
                        MessageProperties.PERSISTENT_BASIC,
                        message.getBody()
                );
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                channel.basicAck(deliveryTag, false); // 确认原消息
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            log.warn("订单重试入队, orderId: {}, 当前重试: {}/{}",
                    orderId, retryCount + 1, PayMQConfig.MAX_RETRY_COUNT);
        } else {
            // 超过最大重试次数，进入死信队列
            try {
                channel.basicNack(deliveryTag, false, false);
                redisTemplate.delete("orders::"+orderId);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            log.error("订单进入死信队列, orderId: {}, 重试次数耗尽", orderId);
        }
    }
    @Autowired
    private OrderFeignClient orderFeignClient;
    /**
     * 处理订单业务
     * @param orderId 订单id
     * @return
     */
    private boolean processOrder(Long orderId) {
        try{
            OrderRequest orderRequest = new OrderRequest();
            orderRequest.setOrderId(orderId);
            //修改订单状态
            orderFeignClient.pay(orderRequest);
            return true;
        }catch (Exception e){
            return false;
        }

    }
}
